from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.db.models import Q
from django.utils.dateparse import parse_datetime
from django.shortcuts import get_object_or_404
from django.http import HttpResponse
import openpyxl
from io import BytesIO
from system.models import User, Department, Role
from system.SysUtils.permission import permission_required, data_permission_required
from system.SysUtils.email_utils import generate_and_send_email_code
from system.SysUtils.mobile_utils import send_mobile_code
from system.SysUtils.rate_limit import ip_rate_limit
from .users_serializers import (
    UserInfoSerializer, UserPageSerializer, UserCreateSerializer, 
    UserFormSerializer, UserUpdateSerializer, UserPasswordResetSerializer,
    UserStatusSerializer, UserProfileUpdateSerializer, UserPasswordChangeSerializer,
    UserEmailUpdateSerializer, DepartmentOptionSerializer, UserMobileUpdateSerializer
)
from system.SysUtils.decorators import log_api
import re
import pandas as pd


class UserInfoView(APIView):
    """获取当前用户信息的视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]

    @log_api('获取当前用户信息', module='用户模块')
    def get(self, request, *args, **kwargs):
        """获取当前登录用户的信息"""
        user = request.user
        serializer = UserInfoSerializer(user)
        
        return Response({
            "code": "00000",
            "data": serializer.data,
            "msg": "一切ok"
        })


class UserPageView(APIView):
    """用户分页查询视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:query"])
    def get(self, request, *args, **kwargs):
        """
        获取用户分页列表
        
        查询参数:
        - keywords: 关键字(用户名/昵称/手机号)
        - status: 用户状态
        - deptId: 部门ID
        - roleIds: 角色ID列表，逗号分隔
        - createTime: 创建时间范围，格式为 startTime,endTime
        - field: 排序字段
        - direction: 排序方向 (ASC/DESC)
        - pageNum: 页码
        - pageSize: 每页记录数
        """
        # 获取查询参数
        keywords = request.query_params.get('keywords', '')
        status = request.query_params.get('status')
        dept_id = request.query_params.get('deptId')
        role_ids = request.query_params.get('roleIds', '')
        create_time = request.query_params.get('createTime', '')
        field = request.query_params.get('field', 'id')
        direction = request.query_params.get('direction', 'DESC')
        page_num = int(request.query_params.get('pageNum', 1))
        page_size = int(request.query_params.get('pageSize', 10))
        
        # 获取数据权限范围
        token = request.headers.get("Authorization")
        viewable_users = data_permission_required(token, "select")
        
        # 构建查询条件
        query = Q(is_deleted=0)  # 只查询未删除的用户
        
        # 添加数据权限过滤
        if viewable_users != "all":
            query &= Q(id__in=viewable_users)
        
        # 关键字查询
        if keywords:
            query &= Q(username__icontains=keywords) | Q(nickname__icontains=keywords) | Q(mobile__icontains=keywords)
        
        # 状态查询
        if status is not None and status != '':
            query &= Q(status=int(status))
        
        # 部门查询
        if dept_id:
            query &= Q(dept_id=dept_id)
        
        # 角色查询
        if role_ids:
            role_id_list = role_ids.split(',')
            query &= Q(roles__id__in=role_id_list)
        
        # 创建时间范围查询
        if create_time:
            time_range = create_time.split(',')
            if len(time_range) == 2:
                start_time = parse_datetime(time_range[0])
                end_time = parse_datetime(time_range[1])
                if start_time and end_time:
                    query &= Q(date_joined__gte=start_time, date_joined__lte=end_time)
        
        # 查询用户总数
        total = User.objects.filter(query).distinct().count()
        
        # 排序
        if direction.upper() == 'ASC':
            order_field = field
        else:
            order_field = f'-{field}'
        
        # 分页查询
        start = (page_num - 1) * page_size
        end = start + page_size
        
        users = User.objects.filter(query).distinct().order_by(order_field)[start:end]
        
        # 序列化
        serializer = UserPageSerializer(users, many=True)
        
        # 返回数据
        return Response({
            "code": "00000",
            "data": {
                "list": serializer.data,
                "total": total
            },
            "msg": "获取用户列表成功"
        })


class UserView(APIView):
    """用户管理视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:add"])
    def post(self, request, *args, **kwargs):
        """
        新增用户
        
        请求体参数:
        - username: 用户名（必需）
        - password: 密码（必需）
        - nickname: 昵称（必需）
        - mobile: 手机号（可选，需符合格式）
        - gender: 性别（可选，默认1）
        - avatar: 头像URL（可选）
        - email: 邮箱（可选）
        - status: 状态（可选，默认1）
        - deptId: 部门ID（可选）
        - roleIds: 角色ID列表（必需）
        - openid: 微信openid（可选）
        """
        serializer = UserCreateSerializer(data=request.data)
        # 创建成功返回用户信息
        if serializer.is_valid():
            serializer.save()
            return Response({
                "code": "00000",
                "data": serializer.data,
                "msg": "用户创建成功"
            })
        else:
            # 返回验证错误信息
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)


class UserFormView(APIView):
    """用户表单信息视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:edit"])
    def get(self, request, user_id, *args, **kwargs):
        """
        获取用户表单信息
        
        路径参数:
        - user_id: 用户ID
        """
        # 获取用户信息
        user = get_object_or_404(User, id=user_id, is_deleted=0)
        
        # 序列化
        serializer = UserFormSerializer(user)
        
        # 返回数据
        return Response({
            "code": "00000",
            "data": serializer.data,
            "msg": "获取用户表单信息成功"
        })


class UserDetailView(APIView):
    """用户详情视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:edit"])
    def put(self, request, ids, *args, **kwargs):
        """
        修改用户
        
        路径参数:
        - ids: 用户ID（必须是单个ID，不支持逗号分隔的多个ID）
        
        请求体参数:
        - username: 用户名（必需）
        - nickname: 昵称（必需）
        - mobile: 手机号（可选，需符合格式）
        - gender: 性别（可选）
        - avatar: 头像URL（可选）
        - email: 邮箱（可选）
        - status: 状态（可选）
        - deptId: 部门ID（可选）
        - roleIds: 角色ID列表（必需）
        - openid: 微信openid（可选）
        """
        # 确保是单个用户ID
        if ',' in ids:
            return Response({
                "code": "A0400",
                "msg": "修改用户时只能指定单个用户ID"
            }, status=400)
        
        try:
            user_id = int(ids)
        except ValueError:
            return Response({
                "code": "A0400",
                "msg": "无效的用户ID格式"
            }, status=400)
            
        # 验证数据权限
        token = request.headers.get("Authorization")
        has_permission = data_permission_required(token, "update", user_id)
        if not has_permission:
            return Response({
                "code": "A0403",
                "msg": "您没有权限修改此用户"
            }, status=403)
            
        # 获取用户信息
        user = get_object_or_404(User, id=user_id, is_deleted=0)
        
        # 序列化并验证数据
        serializer = UserUpdateSerializer(user, data=request.data)
        if serializer.is_valid():
            # 更新用户信息
            serializer.save()
            return Response({
                "code": "00000",
                "data": serializer.data,
                "msg": "用户修改成功"
            })
        else:
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)
    
    @permission_required(["sys:user:delete"])
    def delete(self, request, ids, *args, **kwargs):
        """
        删除用户（逻辑删除）
        
        路径参数:
        - ids: 用户ID，多个以英文逗号(,)分割
        """
        # 解析用户ID列表
        id_list = [int(id.strip()) for id in ids.split(',') if id.strip()]
        
        if not id_list:
            return Response({
                "code": "A0400",
                "msg": "未指定要删除的用户ID"
            }, status=400)
        
        # 获取当前用户ID，避免自己删除自己
        current_user_id = request.user.id
        if current_user_id in id_list:
            return Response({
                "code": "A0401",
                "msg": "不能删除当前登录的用户"
            }, status=400)
        
        # 验证数据权限
        token = request.headers.get("Authorization")
        authorized_ids = []
        unauthorized_ids = []
        
        for user_id in id_list:
            has_permission = data_permission_required(token, "delete", user_id)
            if has_permission:
                authorized_ids.append(user_id)
            else:
                unauthorized_ids.append(user_id)
        
        if unauthorized_ids:
            return Response({
                "code": "A0403",
                "msg": f"您没有权限删除以下用户: {','.join(map(str, unauthorized_ids))}"
            }, status=403)
        
        # 查询要删除的用户
        users = User.objects.filter(id__in=authorized_ids, is_deleted=0)
        
        # 检查是否找到所有用户
        found_ids = list(users.values_list('id', flat=True))
        not_found_ids = set(authorized_ids) - set(found_ids)
        
        if not_found_ids:
            return Response({
                "code": "A0402",
                "msg": f"用户ID {','.join(map(str, not_found_ids))} 不存在或已删除"
            }, status=400)
        
        # 逻辑删除用户
        users.update(is_deleted=1)
        
        return Response({
            "code": "00000",
            "data": {},
            "msg": f"成功删除 {len(found_ids)} 个用户"
        })


class UserTemplateView(APIView):
    """用户导入模板下载视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:import"])
    def get(self, request, *args, **kwargs):
        """
        下载用户导入模板
        
        返回一个Excel文件，包含用户导入的标准格式
        """
        # 创建Excel工作簿和工作表
        workbook = openpyxl.Workbook()
        worksheet = workbook.active
        worksheet.title = "用户导入"
        
        # 设置列标题
        headers = ["用户名", "昵称", "性别", "手机号码", "邮箱", "角色", "部门"]
        for col_num, header in enumerate(headers, 1):
            cell = worksheet.cell(row=1, column=col_num)
            cell.value = header
        
        # 将Excel写入内存
        excel_file = BytesIO()
        workbook.save(excel_file)
        excel_file.seek(0)
        
        # 创建响应
        response = HttpResponse(
            excel_file.getvalue(),
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename="用户导入模板.xlsx"'
        
        return response


class UserPasswordView(APIView):
    """用户密码重置视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:reset-password"])
    def put(self, request, user_id, *args, **kwargs):
        """
        重置用户密码
        
        路径参数:
        - user_id: 用户ID
        
        查询参数:
        - password: 新密码
        """
        # 获取token
        token = request.headers.get('Authorization')
        has_permission = data_permission_required(token, "update", user_id)
        if not has_permission:
            return Response({
                "code": "A0403",
                "msg": "您没有权限重置此用户的密码"
            }, status=403)
        
        # 获取新密码
        password = request.query_params.get('password')
        if not password:
            return Response({
                "code": "A0400",
                "msg": "密码不能为空"
            }, status=400)
        
        # 获取用户信息
        user = get_object_or_404(User, id=user_id, is_deleted=0)
        
        # root用户的密码只能由root自己重置
        if user.username == 'root' and request.user.username != 'root':
            return Response({
                "code": "A0403",
                "msg": "root用户的密码只能由root自己重置"
            }, status=403)
        
        # 序列化并验证数据
        serializer = UserPasswordResetSerializer(user, data={'password': password})
        if serializer.is_valid():
            # 更新用户密码
            serializer.save()
            return Response({
                "code": "00000",
                "data": {},
                "msg": "密码重置成功"
            })
        else:
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)


class UserStatusView(APIView):
    """用户状态修改视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:edit"])
    def patch(self, request, user_id, *args, **kwargs):
        """
        修改用户状态
        
        路径参数:
        - user_id: 用户ID
        
        查询参数:
        - status: 用户状态(1:启用;0:禁用)
        """
        # 获取状态参数
        try:
            status = int(request.query_params.get('status', ''))
        except (ValueError, TypeError):
            return Response({
                "code": "A0400",
                "msg": "状态参数无效，必须为0(禁用)或1(启用)"
            }, status=400)
        
        # 获取用户信息
        user = get_object_or_404(User, id=user_id, is_deleted=0)
        # 获取token
        token = request.headers.get('Authorization')
        has_permission = data_permission_required(token, "update", user_id)
        if not has_permission:
            return Response({
                "code": "A0403",
                "msg": "您没有权限修改此用户状态"
            }, status=403)

        
        # 不允许禁用自己
        if user.id == request.user.id and status == 0:
            return Response({
                "code": "A0401",
                "msg": "不能禁用当前登录的用户"
            }, status=400)
        
        # 不允许禁用root用户
        if user.username == 'root' and status == 0:
            return Response({
                "code": "A0402",
                "msg": "不能禁用root用户"
            }, status=400)
        
        # 序列化并验证数据
        serializer = UserStatusSerializer(user, data={'status': status})
        if serializer.is_valid():
            # 更新用户状态
            serializer.save()
            status_text = "启用" if status == 1 else "禁用"
            return Response({
                "code": "00000",
                "data": {},
                "msg": f"用户{status_text}成功"
            })
        else:
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)


class UserProfileView(APIView):
    """用户个人中心信息视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @log_api('获取个人中心用户信息', module='用户模块')
    def get(self, request, *args, **kwargs):
        """
        获取个人中心用户信息
        
        返回当前登录用户的详细信息
        """
        user = request.user
        
        # 获取部门名称
        dept_name = ""
        if user.dept:
            dept_name = user.dept.name
            
        # 获取角色名称，以逗号分隔
        role_names = ""
        roles = user.roles.all()
        if roles:
            role_names = ", ".join([role.name for role in roles])
            
        # 构建返回数据
        data = {
            "id": user.id,
            "username": user.username,
            "nickname": user.nickname,
            "avatar": user.avatar,
            "gender": user.gender,
            "mobile": user.mobile,
            "email": user.email,
            "deptName": dept_name,
            "roleNames": role_names,
            "createTime": user.date_joined
        }
        
        return Response({
            "code": "00000",
            "data": data,
            "msg": "一切ok"
        })
    
    @log_api('修改个人中心用户信息', module='用户模块')
    def put(self, request, *args, **kwargs):
        """
        修改个人中心用户信息
        
        允许修改的字段：
        - nickname: 用户昵称
        - avatar: 头像URL
        - gender: 性别
        - mobile: 手机号
        - email: 邮箱
        """
        user = request.user
        
        # 使用序列化器验证和更新数据
        serializer = UserProfileUpdateSerializer(user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            
            # 获取更新后的用户信息
            updated_user = User.objects.get(id=user.id)
            
            # 获取部门名称
            dept_name = ""
            if updated_user.dept:
                dept_name = updated_user.dept.name
                
            # 获取角色名称，以逗号分隔
            role_names = ""
            roles = updated_user.roles.all()
            if roles:
                role_names = ", ".join([role.name for role in roles])
                
            # 构建返回数据
            data = {
                "id": updated_user.id,
                "username": updated_user.username,
                "nickname": updated_user.nickname,
                "avatar": updated_user.avatar,
                "gender": updated_user.gender,
                "mobile": updated_user.mobile,
                "email": updated_user.email,
                "deptName": dept_name,
                "roleNames": role_names,
                "createTime": updated_user.date_joined
            }
            
            return Response({
                "code": "00000",
                "data": data,
                "msg": "修改成功"
            })
        else:
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)


class UserPasswordChangeView(APIView):
    """用户密码修改视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @log_api('修改用户密码', module='用户模块')
    def put(self, request, *args, **kwargs):
        """
        修改用户密码
        
        请求体参数:
        - oldPassword: 原密码
        - newPassword: 新密码
        """
        # 使用序列化器验证和更新数据
        serializer = UserPasswordChangeSerializer(
            request.user, 
            data=request.data,
            context={'request': request}
        )
        
        if serializer.is_valid():
            serializer.save()
            return Response({
                "code": "00000",
                "data": {},
                "msg": "密码修改成功"
            })
        else:
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)


class UserEmailCodeView(APIView):
    """
    发送邮箱验证码
    """
    permission_classes = [IsAuthenticated]

    def post(self, request, *args, **kwargs):
        email = request.query_params.get('email')
        if not email:
            return Response({
                'code': '00000',
                'msg': '邮箱不能为空',
                'data': {}
            }, status=400)
        
        # 验证邮箱格式
        if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
            return Response({
                'code': '00000',
                'msg': '邮箱格式不正确',
                'data': {}
            }, status=400)
        
        # 获取当前用户ID
        user_id = request.user.id
        
        # 生成并发送验证码
        result = generate_and_send_email_code(
            email=email,
            subject='邮箱验证码',
            user_id=user_id  # 传递用户ID
        )
        
        if result['success']:
            return Response({
                'code': '00000',
                'msg': '验证码发送成功',
                'data': {}
            })
        else:
            return Response({
                'code': '00000',
                'msg': '验证码发送失败',
                'data': {}
            }, status=500)


class UserEmailUpdateView(APIView):
    """
    绑定或更换邮箱
    """
    permission_classes = [IsAuthenticated]

    def put(self, request, *args, **kwargs):
        # 使用序列化器验证数据
        serializer = UserEmailUpdateSerializer(
            request.user, 
            data=request.data,
            context={'request': request}
        )
        
        if serializer.is_valid():
            # 更新用户邮箱
            serializer.save()
            
            # 返回更新后的邮箱
            return Response({
                'code': '00000',
                'data': {
                    'email': serializer.instance.email
                },
                'msg': '邮箱更新成功'
            })
        else:
            return Response({
                'code': 'A0400',
                'msg': serializer.errors
            }, status=400)


class UserImportView(APIView):
    """
    导入用户
    """
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:import"])
    def post(self, request, *args, **kwargs):
        """
        导入用户
        
        请求体参数:
        - file: Excel文件，第一行是标题，第二行开始是数据
        """
        # 检查是否有文件上传
        if 'file' not in request.FILES:
            return Response({
                'code': 'A0400',
                'msg': '请上传文件',
                'data': None
            }, status=400)
        
        file = request.FILES['file']
        
        # 检查文件类型
        if not file.name.endswith(('.xlsx', '.xls')):
            return Response({
                'code': 'A0400',
                'msg': '请上传Excel文件',
                'data': None
            }, status=400)
        
        # 读取Excel文件
        try:
            df = pd.read_excel(file)
        except Exception as e:
            return Response({
                'code': 'A0400',
                'msg': f'文件读取失败: {str(e)}',
                'data': None
            }, status=400)
        
        # 检查必要的列是否存在
        required_columns = ['用户名', '昵称', '性别', '手机号码', '邮箱', '角色', '部门']
        missing_columns = [col for col in required_columns if col not in df.columns]
        if missing_columns:
            return Response({
                'code': 'A0400',
                'msg': f'文件缺少必要的列: {", ".join(missing_columns)}',
                'data': None
            }, status=400)
        
        # 导入结果统计
        valid_count = 0
        invalid_count = 0
        message_list = []
        
        # 遍历每一行数据
        for index, row in df.iterrows():
            try:
                # 提取数据
                username = str(row['用户名']).strip()
                nickname = str(row['昵称']).strip()
                
                # 处理性别值，支持数字和中文
                gender_value = row['性别']
                if pd.isna(gender_value):
                    gender = 1  # 默认值
                else:
                    gender_str = str(gender_value).strip()
                    if gender_str in ['0', '保密']:
                        gender = 0
                    elif gender_str in ['1', '男']:
                        gender = 1
                    elif gender_str in ['2', '女']:
                        gender = 2
                    else:
                        try:
                            gender = int(gender_str)
                        except ValueError:
                            message_list.append(f'第{index+2}行: 性别值"{gender_str}"不正确，应为0(保密)、1(男)或2(女)')
                            invalid_count += 1
                            continue
                
                mobile = str(row['手机号码']).strip() if pd.notna(row['手机号码']) else None
                email = str(row['邮箱']).strip() if pd.notna(row['邮箱']) else None
                role_names = str(row['角色']).strip() if pd.notna(row['角色']) else None
                dept_name = str(row['部门']).strip() if pd.notna(row['部门']) else None
                
                # 验证数据
                if not username or not nickname:
                    message_list.append(f'第{index+2}行: 用户名和昵称不能为空')
                    invalid_count += 1
                    continue
                
                # 检查用户名是否已存在
                if User.objects.filter(username=username).exists():
                    message_list.append(f'第{index+2}行: 用户名"{username}"已存在')
                    invalid_count += 1
                    continue
                
                # 验证手机号格式
                if mobile and not re.match(r'^1[3-9]\d{9}$', mobile):
                    message_list.append(f'第{index+2}行: 手机号"{mobile}"格式不正确')
                    invalid_count += 1
                    continue
                
                # 验证邮箱格式
                if email and not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
                    message_list.append(f'第{index+2}行: 邮箱"{email}"格式不正确')
                    invalid_count += 1
                    continue
                
                # 验证性别值
                if gender not in [0, 1, 2]:
                    message_list.append(f'第{index+2}行: 性别值"{gender}"不正确，应为0(保密)、1(男)或2(女)')
                    invalid_count += 1
                    continue
                
                # 查找部门
                dept = None
                if dept_name:
                    try:
                        dept = Department.objects.get(name=dept_name)
                    except Department.DoesNotExist:
                        message_list.append(f'第{index+2}行: 部门"{dept_name}"不存在')
                        invalid_count += 1
                        continue
                
                # 查找角色
                roles = []
                if role_names:
                    role_name_list = [name.strip() for name in role_names.split(',')]
                    for role_name in role_name_list:
                        try:
                            role = Role.objects.get(name=role_name)
                            roles.append(role)
                        except Role.DoesNotExist:
                            message_list.append(f'第{index+2}行: 角色"{role_name}"不存在')
                            invalid_count += 1
                            continue
                
                # 创建用户
                user = User.objects.create(
                    username=username,
                    nickname=nickname,
                    gender=gender,
                    mobile=mobile,
                    email=email,
                    dept=dept,
                    status=1,  # 默认启用
                    is_deleted=0  # 默认未删除
                )
                
                # 设置默认密码
                user.set_password('123456')  # 默认密码
                user.save()
                
                # 设置用户角色
                if roles:
                    user.roles.set(roles)
                
                valid_count += 1
                
            except Exception as e:
                message_list.append(f'第{index+2}行: 导入失败 - {str(e)}')
                invalid_count += 1
        
        # 返回导入结果
        return Response({
            'code': '00000',
            'data': {
                'validCount': valid_count,
                'invalidCount': invalid_count,
                'messageList': message_list
            },
            'msg': f'导入完成，成功导入{valid_count}条数据，失败{invalid_count}条'
        })


class UserExportView(APIView):
    """
    导出用户
    """
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:export"])
    def get(self, request, *args, **kwargs):
        """
        导出用户
        
        查询参数:
        - keywords: 关键字(用户名/昵称/手机号)
        - status: 用户状态
        - deptId: 部门ID
        - roleIds: 角色ID列表，逗号分隔
        - createTime: 创建时间范围，格式为 startTime,endTime
        - field: 排序字段
        - direction: 排序方向 (ASC/DESC)
        - pageNum: 页码
        - pageSize: 每页记录数
        """
        # 获取查询参数
        keywords = request.query_params.get('keywords', '')
        status = request.query_params.get('status')
        dept_id = request.query_params.get('deptId')
        role_ids = request.query_params.get('roleIds', '')
        create_time = request.query_params.get('createTime', '')
        field = request.query_params.get('field', 'id')
        direction = request.query_params.get('direction', 'DESC')
        page_num = int(request.query_params.get('pageNum', 1))
        page_size = int(request.query_params.get('pageSize', 10))
        
        # 构建查询条件
        query = Q(is_deleted=0)  # 只查询未删除的用户
        
        # 关键字查询
        if keywords:
            query &= Q(username__icontains=keywords) | Q(nickname__icontains=keywords) | Q(mobile__icontains=keywords)
        
        # 状态查询
        if status is not None and status != '':
            query &= Q(status=int(status))
        
        # 部门查询
        if dept_id:
            query &= Q(dept_id=dept_id)
        
        # 角色查询
        if role_ids:
            role_id_list = role_ids.split(',')
            query &= Q(roles__id__in=role_id_list)
        
        # 创建时间范围查询
        if create_time:
            time_range = create_time.split(',')
            if len(time_range) == 2:
                start_time = parse_datetime(time_range[0])
                end_time = parse_datetime(time_range[1])
                if start_time and end_time:
                    query &= Q(date_joined__gte=start_time, date_joined__lte=end_time)
        
        # 排序
        if direction.upper() == 'ASC':
            order_field = field
        else:
            order_field = f'-{field}'
        
        # 查询用户
        users = User.objects.filter(query).distinct().order_by(order_field)
        
        # 创建Excel工作簿和工作表
        workbook = openpyxl.Workbook()
        worksheet = workbook.active
        worksheet.title = "用户列表"
        
        # 设置列标题
        headers = ["用户名", "用户昵称", "部门", "性别", "手机号码", "邮箱", "创建时间"]
        for col_num, header in enumerate(headers, 1):
            cell = worksheet.cell(row=1, column=col_num)
            cell.value = header
        
        # 填充数据
        for row_num, user in enumerate(users, 2):
            # 获取部门名称
            dept_name = user.dept.name if user.dept else ""
            
            # 获取性别文本
            gender_text = ""
            if user.gender == 0:
                gender_text = "保密"
            elif user.gender == 1:
                gender_text = "男"
            elif user.gender == 2:
                gender_text = "女"
            
            # 格式化创建时间
            create_time_str = user.date_joined.strftime("%Y/%m/%d %H:%M:%S") if user.date_joined else ""
            
            # 填充单元格
            worksheet.cell(row=row_num, column=1, value=user.username)
            worksheet.cell(row=row_num, column=2, value=user.nickname)
            worksheet.cell(row=row_num, column=3, value=dept_name)
            worksheet.cell(row=row_num, column=4, value=gender_text)
            worksheet.cell(row=row_num, column=5, value=user.mobile)
            worksheet.cell(row=row_num, column=6, value=user.email)
            worksheet.cell(row=row_num, column=7, value=create_time_str)
        
        # 调整列宽
        for col in worksheet.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                if cell.value:
                    max_length = max(max_length, len(str(cell.value)))
            adjusted_width = (max_length + 2)
            worksheet.column_dimensions[column].width = adjusted_width
        
        # 将Excel写入内存
        excel_file = BytesIO()
        workbook.save(excel_file)
        excel_file.seek(0)
        
        # 创建响应
        response = HttpResponse(
            excel_file.getvalue(),
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename="用户列表.xlsx"'
        
        return response


class UserOptionsView(APIView):
    """
    获取用户选项列表
    """
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:user:query"])
    def get(self, request, *args, **kwargs):
        """
        获取用户选项
        
        返回用户列表，用于下拉选择
        """
        # 检查数据权限
        token = request.headers.get("Authorization")
        data_permission = data_permission_required(token, "select")
        
        # 构建查询条件
        query = Q(is_deleted=0, status=1)
        
        # 添加数据权限过滤
        if isinstance(data_permission, list) and data_permission:
            # 如果返回的是用户ID列表，只查询这些用户
            query &= Q(id__in=data_permission)
        
        # 查询用户数据
        users = User.objects.filter(query).order_by('id')
        
        # 准备返回数据
        result = []
        for user in users:
            result.append({
                "value": str(user.id),
                "label": user.nickname or user.username
            })
        
        return Response({
            "code": "00000",
            "data": result,
            "msg": "一切ok"
        })


class UserMobileCodeView(APIView):
    """
    发送手机验证码
    """
    permission_classes = [IsAuthenticated]

    @ip_rate_limit(60)  # 限制同一IP每60秒发送一次
    def post(self, request, *args, **kwargs):
        """
        发送手机验证码
        
        查询参数:
        - mobile: 手机号码
        """
        mobile = request.query_params.get('mobile')
        if not mobile:
            return Response({
                'code': 'A0400',
                'msg': '手机号不能为空',
                'data': None
            }, status=400)
        
        # 验证手机号格式
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({
                'code': 'A0401',
                'msg': '手机号格式不正确',
                'data': None
            }, status=400)
        
        # 获取当前用户ID
        user_id = request.user.id
        
        # 发送短信验证码
        result = send_mobile_code(mobile, user_id)  # 传递用户ID
        
        if result['success']:
            return Response({
                'code': '00000',
                'data': {},
                'msg': '验证码发送成功'
            })
        else:
            return Response({
                'code': 'A0500',
                'data': None,
                'msg': result['message']
            }, status=500)


class UserMobileUpdateView(APIView):
    """
    绑定或更换手机号
    """
    permission_classes = [IsAuthenticated]

    def put(self, request, *args, **kwargs):
        """
        绑定或更换手机号
        
        请求体参数:
        - mobile: 新手机号
        - code: 验证码
        """
        # 使用序列化器验证数据
        serializer = UserMobileUpdateSerializer(
            request.user, 
            data=request.data,
            context={'request': request}
        )
        
        if serializer.is_valid():
            # 更新用户手机号
            serializer.save()
            
            # 返回更新后的手机号
            return Response({
                'code': '00000',
                'data': {
                    'mobile': serializer.instance.mobile
                },
                'msg': '手机号更新成功'
            })
        else:
            return Response({
                'code': 'A0400',
                'msg': serializer.errors
            }, status=400)
